package com.apes.autoparts.parts.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.autoparts.parts.model.*;
import com.apes.autoparts.parts.repository.*;
import com.apes.framework.api.DomainService;
import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.google.common.collect.Lists;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import oracle.sql.TIMESTAMP;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by lishikun on 2020/10/13 19:28
 */
@Service("timedTaskAutoPartsService")
public class TimedTaskAutoPartsService{

    @Autowired
    private VinModelRepository vinModelRepository;
    @Autowired
    private QueryMainGroupService queryMainGroupService;
    @Autowired
    private MainGroupRepository mainGroupRepository;
    @Autowired
    private SubGroupRepository subGroupRepository;
    @Autowired
    private PartRepository partRepository;
    @Autowired
    private QuerySubGroupService querySubGroupService;
    @Autowired
    private QueryPartsService queryPartsService;
    @Autowired
    private SubGroupImgRepository subGroupImgRepository;
    @Autowired
    private VinLabelModelRepository vinLabelModelRepository;
    @Autowired
    private QueryVinService queryVinService;
    private Long second = 10L;  // 执行周期

    private Timer timer = new Timer();

    private JSONArray jsonArray = null; // 记录当前执行的数据

    private int size = 0; // 记录总执行次数





    VinLabelModel vinLabelModel;


    private List<String> methodNameArray = new ArrayList(); // 当前执行的方法对象List

    private int methodNameIndex = 0; // 当前执行的方法 index
//    ["queryMainGroup","querySubGroup","querySubGroupImg","queryParts"]

    private List<VinLabelModel> vinLabelModels = null;
    private List<VinModel> vinModels = null;

    // 存储当前数据
    private List<MainGroup> mainGroups = null;
    private List<SubGroup> subGroups = null;
    private List<SubGroupImg> subGroupImgs = null;
    private List<Part> parts = null;


    /**
     * 流程--->初始化，获取一个未解析的vin或者一个数据超过90天的vin---> 获取vin的数据 ---> 获取vin下的主组数据 ---> 获取v每一个主组下的子组数据 （解析完毕，才进去下一层）--->
     *         获取子组下的热点图（解析完毕，才进行下一步） --->获取子组下的配件（完）
     * @param request
     * @throws Exception
     */

    public JSONObject timedTaskAutoParts(SimpleRequest request) {

        /**
         * 初始化数据
         */

        methodNameIndex = 0;
        vinLabelModels = new ArrayList<>();
        vinModels = new ArrayList<>();
        vinLabelModel = null;

        mainGroups = new ArrayList<>();
        subGroups = new ArrayList<>();
        subGroupImgs = new ArrayList<>();
        parts = new ArrayList<>();
        if (methodNameArray.size() == 0) {
            methodNameArray.add("queryVinModel");
            methodNameArray.add("queryMainGroup");
            methodNameArray.add("querySubGroup");
            methodNameArray.add("querySubGroupImg");
            methodNameArray.add("queryParts");

        }
        Calendar calendar1 = Calendar.getInstance();
        calendar1.add(Calendar.DATE, -90);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Timestamp timestamp = Timestamp.valueOf(sdf.format(calendar1.getTime()));
        vinLabelModels = vinLabelModelRepository.findAll(JpaDsl.toCriteriaByEq("vin", "LGBH52E03HY344162"));



        for (int l = 0; l < vinLabelModels.size(); l++) {


            if ( !vinLabelModels.get(l).isParsing()) {
                vinLabelModel = vinLabelModels.get(l);
                break;
            }
            /**
             * 数据超过90天
             */
            if ( vinLabelModels.get(l).getLastUpdatedStamp().getTime() < timestamp.getTime()) {
                vinLabelModel = vinLabelModels.get(l);
                vinLabelModel.setParsing(false);
                vinLabelModelRepository.saveAndFlush(vinLabelModel);
                break;
            }
            /***
             *  测试奔驰特殊数据
             */
//            if ("WDC0J6EB7KF513072".equals(vinLabelModels.get(l).getVin())) {
//                vinLabelModel = vinLabelModels.get(l);
//                break;
//            }
        }

        if (vinLabelModel != null) {
            try {
                asynTimedTaskAutoParts();
            }catch (Exception e) {
                throw new RuntimeException("接口调通错误：" + e);
            }

        }


        JSONObject json = new JSONObject();
        json.put("message", "成功");
        return json;

    }


    /***
     * 功能： 判断当前执行的函数
     * @throws Exception
     */
    private void asynTimedTaskAutoParts() throws Exception {

        if (methodNameArray.get(methodNameIndex).equals("queryVinModel")){
            System.out.println("解析vin中------------------------------------");

            timedTaskVinModel();

            System.out.println("解析vin完毕----------------------------------");
        } else if (methodNameArray.get(methodNameIndex).equals("queryMainGroup")) {
            System.out.println("解析主组中------------------------------------");

            timedTaskMainGroup();

            System.out.println("解析主组完毕----------------------------------");
        } else if (methodNameArray.get(methodNameIndex).equals("querySubGroup")) {
            System.out.println("解析子组中------------------------------------");

            timedTaskSubGroup();

            System.out.println("解析子组完毕----------------------------------");

        } else if (methodNameArray.get(methodNameIndex).equals("querySubGroupImg")) {
            System.out.println("解析热点图中----------------------------------");

            timedTaskSubGroupImg();

            System.out.println("解析热点图完毕--------------------------------");

        } else {
            System.out.println("解析配件中------------------------------------");

            timedTaskPart();

            System.out.println("解析配件完毕----------------------------------");

        }



        return;
    }

    // 定时任务车架号
    private void timedTaskVinModel() throws Exception {

        Calendar calendar1 = Calendar.getInstance();
        calendar1.add(Calendar.DATE, -90);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Timestamp timestamp = Timestamp.valueOf(sdf.format(calendar1.getTime()));
        vinModels = vinModelRepository.findAll(
                JpaDsl.toCriteria(
                        "vin", "EQ" , vinLabelModel.getVin(),
                        "createDate" ,"GT", timestamp
                ));

        if (vinModels.size() > 0) {

            /**
             * TODO
             * 主组本地数据与远端的数据不一致
             */
            methodNameIndex = methodNameIndex + 1;

            asynTimedTaskAutoParts();
            return;

        } else {
            JSONObject param = new JSONObject();
            // 设置获取车架号的主组信息的参数
            param.put("vin", vinLabelModel.getVin());

            vinModels = queryVinService.queryVinModels(param, vinLabelModel);
            if (vinModels == null) return;
            vinModels.forEach(vinModel -> {
                vinModel.getSelectorId().setPZCXID(vinLabelModel.getPZCXID());
                vinModel.getSelectorId().setQCCPMC(vinLabelModel.getQCCPMC());
            });
            vinModels.forEach(vinModel -> {
                vinModelRepository.saveAndFlush(vinModel);
            });

        }


    }

    // 定时任务获取车架号的主组数据
    private void timedTaskMainGroup() throws Exception {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.add(Calendar.DATE, -90);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Timestamp timestamp = Timestamp.valueOf(sdf.format(calendar1.getTime()));
        vinModels = vinModelRepository.findAll(JpaDsl.toCriteria(
                "vin", "EQ", vinLabelModel.getVin(),
                "createDate" ,"GT", timestamp
        ));


        for (int l = 0; l < vinModels.size(); l++) {

            if ( vinModels.get(l).getSelectorId().getSelectorId() == null) {
                vinLabelModel.setParsing(true);
                vinLabelModelRepository.saveAndFlush(vinLabelModel);
                continue;
            }
            List<MainGroup> mainGroupList = mainGroupRepository.findAll(
                    JpaDsl.toCriteria(
                            "orgSelectorId.selectorId", "EQ", vinModels.get(l).getSelectorId().getSelectorId(),
                            "createDate" ,"GT", timestamp
                    )
            );



            if (mainGroupList != null) {
                mainGroupList.forEach(mainGroup -> {
                    mainGroups.add(mainGroup);
                });
            }

        }



        if ( mainGroups != null && mainGroups.size() > 0 && vinModels.size() > 0) {

            methodNameIndex = (methodNameIndex + 1) % 5;
            asynTimedTaskAutoParts();
            return;
        }
        for (int o = 0; o < vinModels.size(); o++) {

            JSONObject param = new JSONObject();

            // 设置获取车架号的主组信息的参数
            param.put("vin", vinModels.get(o).getVin());
            param.put("brandCode", vinModels.get(o).getSelectorId().getBrandCode());
            param.put("id", vinModels.get(o).getSelectorId().getSelectorId());

            // 获取车架号主组的信息
            mainGroups = queryMainGroupService.queryMainGroupAll(param);

        }


    }

    // 定时任务获取主组的子组数据
    private void timedTaskSubGroup() throws Exception {

        int l;
        Calendar calendar1 = Calendar.getInstance();
        calendar1.add(Calendar.DATE, -90);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Timestamp timestamp = Timestamp.valueOf(sdf.format(calendar1.getTime()));
        for (l = 0; l < mainGroups.size(); l++) {
            Boolean isNotData = false;
            /**
             * 筛选出有效的主组
             */
            if ( mainGroups.get(l).isHasNext() && mainGroups.get(l).isValid() ) {

                subGroups = subGroupRepository.findAll(
                        JpaDsl.toCriteria(
                                "mainGroupId.id", "EQ", mainGroups.get(l).getId()
                                ,
                                "createDate" ,"GT", timestamp
                        )
                );

                if (subGroups.size() == 0) {
                    JSONObject param = new JSONObject();
                    // 设置获取车架号的主组信息的参数
                    param.put("vin", vinLabelModel.getVin());
                    try {
                        for (int n = 0; n < vinModels.size(); n++) {
                            param.put("brandCode", mainGroups.get(l).getOrgSelectorId().getBrandCode());

                            /**
                             * 处理奔驰的特殊情况
                             */
                            if ( mainGroups.get(l).getSelectorId() != null && !"0".equals(mainGroups.get(l).getSelectorId()) )
                                param.put("selectorId", mainGroups.get(l).getSelectorId());
                            else
                                param.put("selectorId", mainGroups.get(l).getOrgSelectorId().getSelectorId());


                            param.put("id", mainGroups.get(l).getMainGroupId());

                            subGroups = querySubGroupService.querySubGroupAll(param);

                            if (subGroups.size() != 0) {
                                int finalL = l;
                                subGroups.forEach(subGroup -> {
                                    subGroup.setMainGroupId(mainGroups.get(finalL));
                                    subGroup.setOrgSelectorId(mainGroups.get(finalL).getOrgSelectorId());
                                    subGroupRepository.saveAndFlush(subGroup);

                                });
                            } else {
                                isNotData = true;
                            }
                        }

                    }
                    catch (Exception e) {
                        e.printStackTrace();
                        vinLabelModel.setMassger("\n" + e.getMessage() + vinLabelModel.getMassger() +" \n   保存子组图片失败。\n");
                        vinLabelModelRepository.saveAndFlush(vinLabelModel);
                        continue;
                    }
                    if (isNotData) continue;

                    break;

                }

            } else {

                continue;
            }
        }


        if (l < mainGroups.size()) {

            return;
        } else {
            methodNameIndex = (methodNameIndex + 1) % 5;
            subGroups = new ArrayList<>();
            for (int o = 0; o < mainGroups.size(); o++) {
                List<SubGroup> subGroupList = subGroupRepository.findAll(
                        JpaDsl.toCriteria(
                                "mainGroupId.id", "EQ", mainGroups.get(o).getId(),
                                "createDate" ,"GT", timestamp
                        )
                );
                subGroupList.forEach(subGroup -> {
                    subGroups.add(subGroup);
                });

            }
            asynTimedTaskAutoParts();
        }

    }

    // 定时任务获取子组的热点图数据
    private void timedTaskSubGroupImg() throws Exception {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.add(Calendar.DATE, -90);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Timestamp timestamp = Timestamp.valueOf(sdf.format(calendar1.getTime()));
        int l;
        List<String> subGroupIds = new ArrayList<>();
        subGroups.forEach(subGroup -> {
            subGroupIds.add(subGroup.getId());
        });

        List<List<String>> splitList = getSplitList(subGroupIds);
        List<String> partBySubGroupId = Lists.newArrayList();
        for (int i = 0; i < splitList.size(); i++) {
            List<String> subGroupImgBySubGroupId = subGroupImgRepository.findSubGroupImgBySubGroupId(splitList.get(i), timestamp);
            subGroupImgBySubGroupId.forEach(subGroupImg ->{
                partBySubGroupId.add(subGroupImg);
            });

        }
        Map<String,Boolean> partsSubGroupIdMap = new HashMap<>();
        partBySubGroupId.forEach(item-> partsSubGroupIdMap.put(item,true) );
        for (l = 0; l < subGroups.size(); l++) {

            /**
             * 筛选出无效的子组
             */

            if ( partsSubGroupIdMap.get(subGroups.get(l).getId()) == null && subGroups.get(l).isBelongTo() && subGroups.get(l).isValid()) {
                JSONObject param = new JSONObject();
                // 设置获取车架号的主组信息的参数
                /**
                 *  处理热点图异常
                 *  保存热点图的地址到ftp服务器的时候，可能不存在
                 */
                try {
                    param.put("vin", vinLabelModel.getVin());

                    for (int n = 0; n < vinModels.size(); n++) {

                        param.put("brandCode", subGroups.get(l).getOrgSelectorId().getBrandCode());
                        if ( subGroups.get(l).getMainGroupId().getSelectorId() != null && !"0".equals(subGroups.get(l).getMainGroupId().getSelectorId()) ) {
                            param.put("selectorId", subGroups.get(l).getMainGroupId().getSelectorId());
                            param.put("mainGroupId", subGroups.get(l).getMainGroupCode());
                        }

                        else{
                            param.put("selectorId", subGroups.get(l).getOrgSelectorId().getSelectorId());
                            param.put("mainGroupId", subGroups.get(l).getMainGroupCode());

                        }

                        param.put("id", subGroups.get(l).getSubGroupId());
                        subGroupImgs = querySubGroupService.queryImgPointAll(param);


                        int finalL = l;
                        subGroupImgs.forEach(subGroupImg -> {
                            subGroupImg.setSubGroupId(subGroups.get(finalL));
                            subGroupImgRepository.saveAndFlush(subGroupImg);
                        });

                        continue;
                    }
                }
                catch (Exception e) {
                    e.printStackTrace();
                    vinLabelModel.setMassger(e.getMessage() + vinLabelModel.getMassger() +"    保存热点图片失败。\n"
                    );
                    vinLabelModelRepository.saveAndFlush(vinLabelModel);
                    continue;
                }
                if (subGroupImgs == null || subGroupImgs.size() == 0) continue;
                break;

            }

        }

        if (l < subGroups.size()) {

            return;
        } else {
            methodNameIndex = (methodNameIndex + 1) % 5;
            asynTimedTaskAutoParts();
        }

    }

    // 定时任务获取子组的零件数据
    private void timedTaskPart() throws Exception {
        int l;

        /***
         * 获取已解析的子组编码并转成map
         */
        Calendar calendar1 = Calendar.getInstance();
        calendar1.add(Calendar.DATE, -90);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Timestamp timestamp = Timestamp.valueOf(sdf.format(calendar1.getTime()));

        List<String> subGroupIds = new ArrayList<>();
        subGroups.forEach(subGroup -> {
            subGroupIds.add(subGroup.getId());
        });

        List<List<String>> splitList = getSplitList(subGroupIds);
        List<String> partBySubGroupIds = Lists.newArrayList();
        for (int i = 0; i < splitList.size(); i++) {
            List<String> partsBySubGroupId = partRepository.findPartBySubGroupId(splitList.get(i), timestamp);
            partsBySubGroupId.forEach(part ->{
                partBySubGroupIds.add(part);
            });

        }

        Map<String,Boolean> partsSubGroupIdMap = new HashMap<>();
        partBySubGroupIds.forEach(item-> partsSubGroupIdMap.put(item,true) );


        for (l = 0; l < subGroups.size(); l++) {

            /**
             * 筛选出无效的子组
             */
            if ( partsSubGroupIdMap.get(subGroups.get(l).getId()) == null && subGroups.get(l).isBelongTo() && subGroups.get(l).isValid() ) {

                JSONObject param = new JSONObject();
                // 设置获取车架号的主组信息的参数
                param.put("vin", vinLabelModel.getVin());
                for (int n = 0; n < vinModels.size(); n++) {
                    param.put("brandCode", subGroups.get(l).getOrgSelectorId().getBrandCode());

                    /**
                     * 处理奔驰的特殊情况
                     */
                    if (subGroups.get(l).getMainGroupId().getSelectorId() != null && !"0".equals(subGroups.get(l).getMainGroupId().getSelectorId())) {
                        param.put("selectorId", subGroups.get(l).getMainGroupId().getSelectorId());
                        param.put("mainGroupId", subGroups.get(l).getMainGroupCode());
                    }
                    else{
                        param.put("selectorId", subGroups.get(l).getOrgSelectorId().getSelectorId());
                        param.put("mainGroupId", subGroups.get(l).getMainGroupCode());
                    }

                    param.put("id", subGroups.get(l).getSubGroupId());

                    /**
                     * 处理零件数据
                     */
                    parts = queryPartsService.queryParts(param);
                    int finalL = l;
                    parts.forEach(part -> {
                        part.setSubGroupId( subGroups.get(finalL));
                        part.setOrgSelectorId(subGroups.get(finalL).getOrgSelectorId());
                        part.setMainGroupId(subGroups.get(finalL).getMainGroupId());
                        partRepository.saveAndFlush(part);
                    });
                }
                if (parts.size() == 0) continue;
                break;
            } else {
                continue;
            }
        }

        if (l >= subGroups.size()) {
            vinLabelModel.setParsing(true);
            vinLabelModel.setLastUpdatedStamp(new Date());
            vinLabelModelRepository.saveAndFlush(vinLabelModel);
        }
        return;


    }


    public List<List<String>> getSplitList(List<String> subGroupIds) {
        List<List<String>> groupList = Lists.newArrayList();
        List<String> newList = Lists.newArrayList(subGroupIds);
        int len = newList.size();

        int num = len % 800 == 0 ? len / 800 : (len / 800 + 1);
        for (int i = 0; i < num; i++) {

            groupList.add(subGroupIds.subList(i * 800, (i+1) * 800 > len ? len : (i+1) * 800  ));
        }
        return groupList;

    }



}
